﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Com.Common.Util.Cache;
using Microsoft.ApplicationServer.Caching;

namespace Com.Azure.Common.Util.Cache
{
    /// <summary>
    /// Azure角色缓存: Microsoft.ApplicationServer.Caching.DataCache
    /// </summary>
    public class AzureCacheService : ICache
    {
        private static DataCache defaultCache;
        private static HashSet<string> CacheKeyList = new HashSet<string>();
        private static DataCacheNotificationDescriptor ndCacheLvlAllOps;
        static AzureCacheService()
        {
            var config = new DataCacheFactoryConfiguration("default");
            var cacheFactory = new DataCacheFactory(config);
            defaultCache = cacheFactory.GetDefaultCache();
            var cacheOperations = DataCacheOperations.AddItem | DataCacheOperations.RemoveItem;
            ndCacheLvlAllOps = defaultCache.AddCacheLevelCallback(cacheOperations, CacheLvlDelegate);
        }

        public T GetCache<T>(string key)
        {
            return (T)defaultCache.Get(key);
        }
        public object GetCache(Type type, string key)
        {
            var objString = defaultCache.Get(key);
            if (type == typeof(string))
            {
                return objString.ToString();
            }

            return objString;
        }

        public void SetCache<T>(string key, T obj) 
        {
            //if (CacheKeyList.Contains(key))
            //    throw new ArgumentException("Azure InRole缓存中已存在重复的键值: " + key + "，请更改缓存键值再重试！", "key");
            
            defaultCache.Put(key, obj);
            //CacheKeyList.Add(key);
        }

        public void SetCache<T>(string key, T obj, TimeSpan slidingExpiration)
        {
            //if (CacheKeyList.Contains(key))
            //    throw new ArgumentException("Azure InRole缓存中已存在重复的键值: " + key + "，请更改缓存键值再重试！", "key");
            
            defaultCache.Put(key, obj, slidingExpiration);
            //CacheKeyList.Add(key);
        }

        public void SetCache<T>(string key, T obj, DateTime absoluteExpiration)
        {
            //if (CacheKeyList.Contains(key))
            //    throw new ArgumentException("Azure InRole缓存中已存在重复的键值: " + key + "，请更改缓存键值再重试！", "key");
            
            var slidingExpiration = absoluteExpiration.Subtract(DateTime.UtcNow);
            defaultCache.Put(key, obj, slidingExpiration);
            //CacheKeyList.Add(key);
        }

        public void RemoveCache(string key)
        {
            defaultCache.Remove(key);
            //CacheKeyList.Remove(key);
        }

        public void RemoveAllCache()
        {
            defaultCache.Clear();
            CacheKeyList.Clear();
        }

        private static void CacheLvlDelegate(string cacheName, string region, string key, DataCacheItemVersion itemVersion, DataCacheOperations operationId, DataCacheNotificationDescriptor nd)
        {
            if (operationId == DataCacheOperations.AddItem)
            {
                if (!CacheKeyList.Contains(key))
                    CacheKeyList.Add(key);
            }
            else if (operationId == DataCacheOperations.RemoveItem)
            {
                if (CacheKeyList.Contains(key))
                    CacheKeyList.Remove(key);
            }
        }

        public List<string> GetCacheKeyList()
        {
            return CacheKeyList.ToList();
        }

        public bool ExistKey(string key)
        {
            return CacheKeyList.Contains(key);
        }

        public int DatabaseId { get; set; }
    }
}
